import os
import sys
import time
import rapidUtils
import createIndex
import c_stemming
import normalizeQuery
import math
import pagerank

morfBases = []
stemming = False

if len(sys.argv) >= 2 and sys.argv[1] == 's':
    stemming = True
    createIndex.loadNode("nodeStaticStem.dat")
    print 'Dictionary ready!'
    createIndex.loadIndex("serializeStem.dat")
    print 'Index ready!'
elif len(sys.argv) >= 2 and  sys.argv[1] == 'n':
    stemming = False
    createIndex.loadNode("nodeStaticNoStem.dat")
    print 'Dictionary ready!'
    createIndex.loadIndex("serializeNoStem.dat")
    print 'Index ready!'
else:    
    stemming = True
    createIndex.loadNode("nodeStaticStem.dat")
    print 'Dictionary ready!'
    createIndex.loadIndex("serializeStem.dat")
    print 'Index ready!'


morfo = open('morfo3.txt')


for line in morfo:
   tokens = line.split()
   temp = []
   for elem in tokens[1:]:
        stemmToken = c_stemming.stemmToken( elem ) 
        if stemmToken is not None:
            number = createIndex.getVal( stemmToken )
            if number > 0 :
                temp.append( number )          
        number = createIndex.getVal( elem )
        if number > 0 :
            temp.append( number )          
   morfBases.append(  temp )

morfBases = tuple( morfBases )   

assert len(morfBases) == 971575
   
print 'Morfo ready!'

wiki = open('titlesPR')

titles = [None]
article = 1
numbersForTitles = [None]
pageRankForTitles = [None]

for line in wiki:
    t = line.split("##")
    titles.append( t[0] )
    numbersForTitles.append( int( t[1] ) )
    if len( t ) > 2 :
        pageRankForTitles.append( float( t[2]  ) )  
    else:
        pageRankForTitles.append( 0 )


tables = tuple( [-0.038, 0.0112, 0.0024, -0.20, 0.049, 0.012, -0.0029, 0.05, 0.57, -0.055, 0.3, 0.2] )

rapidUtils.getTables(  pageRankForTitles, numbersForTitles, pagerank.getPointerToScore(),tables )
rapidUtils.setConstans( tables )

titles = tuple(titles)

print 'Titles ready!'


    
print "I'm ready to serve!"

def orArticles(e1,e2):
    ans =  rapidUtils.orArticles(e1,e2)
    return ans

def andArticles(e1,e2):
    ans = rapidUtils.andArticles(e1,e2)
    return ans

def getArticlesFromIndex(n):
    return createIndex.get(n)
    
def orListArticles(l):
    i = 0
    answer = (0, 0, 0, 1)
    for elem in l:
        if i == 0:
            i = 1
            answer = elem
            continue
        answer = orArticles(answer ,elem)
    return answer
        
def andListArticles(l):
    i = 0
    answer = (0, 0, 0, 1)
    for elem in l:
        if i == 0:
            i = 1
            answer = elem
            continue
        answer = andArticles(answer ,elem)
    return answer
    
def getNumbersForWord(word):
    answer = []
    number = createIndex.getVal(word) - 1
    if number < 971575 and number > 0:
        if len( morfBases[number] ) > 0 :
            answer = morfBases[number]

    sToken = c_stemming.stemmToken(word) 
    i = -1
    
    
    if sToken is not None:
        i = createIndex.getVal(sToken)
    
    j = createIndex.getVal(word)
    
    if i > 0:
        answer = answer + [i]
    if j > 0:
        answer = answer + [j]
    
    #print answer
    return answer

def getArticlesForWord(word):
    answer = []
    for elem in getNumbersForWord(word):
        answer.append( getArticlesFromIndex(elem) )
    return orListArticles( answer )
                    
def queryArticles(napis):
    napis = normalizeQuery.normalize(napis)
    andQueries = napis.split(" ")
    answerAnd = []
    for andQuery in andQueries:
        split = andQuery.split("|")
        split = [ getArticlesForWord(elem) for elem in split ]
        answerAnd.append( orListArticles( split ) )
    return andListArticles( answerAnd )



#przepisane do osobnej funkcji dla profilera
def change(l1,l2):
    rapidUtils.change(l1,l2)

#przepisane do osobnej funkcji dla profilera    
def ruget(l):
    return rapidUtils.get(l)

def queryAny(line):
    t = queryArticles(line)
    lista = rapidUtils.getArticles(t)
    
    liczbaTur = pagerank.iterujPR(50,t,5000)
    change(liczbaTur,t)
    t = ruget(t)
    return t

   
def test():
    q = 0
    start = time.time()
    i  = 0
    pytania = open('pytania_and_dla_IR.txt')
    odpowiedzi = open('odpowiedzi_na_' + 'pytania_and_dla_IR.txt','w')
    for line in pytania:
      i += 1
      lista = queryAny(line.strip())
      odpowiedzi.write( 'QUERY: ' + line.strip() + ' TOTAL: ' + str(len(lista)) + '\n')
      for elem in lista:
        if 0 <= elem - 1 < len(titles) -1 : 
            odpowiedzi.write( titles[elem ].strip() + '\n')
        else:
            print 'Niespodziewane zachowanie :( ' + str(elem)

    end = time.time()
    print str( i ) + ' queries'
    print str( (end - start) / i ) + ' seconds per query'
    print str( (end - start) ) + ' seconds total'
            
    
if __name__ == '__main__':
    if len( sys.argv ) >= 3:

        start = time.time()
        i  = 0
        pytania = open(sys.argv[2])
        odpowiedzi = open('odpowiedzi_na_' + sys.argv[2],'w')        
        for line in pytania:
          i += 1
          lista = queryAny(line.strip())
          #odpowiedzi.write( 'QUERY: ' + line.strip() + ' TOTAL: ' + str(len(lista)) + '\n')
          odpowiedzi.write( 'QUERY: ' + line.strip() + '\n')
            
          for elem in lista:
            if 0 <= elem - 1 < len(titles) -1 :     
                odpowiedzi.write( titles[elem ].strip() + '\n')
                
          odpowiedzi.write('\n')
        end = time.time()
        print str( (end - start) / i ) + ' seconds per query'
        print str( (end - start) ) + ' seconds total'

    else:
        log = open("log.dat",'w')
        print '! is for quit'
        while True:
            line = raw_input('>')
            if line.strip() == '!':
                break
                log.close()
            start = time.time()
            lista = queryAny(line.strip())
            end = time.time()
            
            log.write( 'QUERY: ' + line.strip() + ' TOTAL: ' + str(len(lista)) + '\n')
            print 'QUERY: ' + line.strip() + ' TOTAL: ' + str(len(lista))
            for elem in lista:
              if 0 <= elem - 1 < len(titles) -1 : 
                print titles[elem ].strip(), elem
                log.write( str(titles[elem].strip() ) + ' ' + str(elem) + '\n')

            print str( (end - start) ) + ' seconds per query'        
            log.write( str( (end - start) ) + ' seconds per query\n')
            log.flush()
